function varargout = genSDD(modelName, varargin)
%GENSDD 从模型生成系统设计描述(SDD)报告
%   此函数从指定的Simulink模型生成系统设计描述（System Design Description, SDD）报告。
%   SDD报告是DO-178C标准中的重要文档，详细描述了系统的设计和架构。
%
%语法:
%   genSDD(modelName)
%   genSDD(modelName, authorNames)
%   genSDD(modelName, authorNames, 'CI')
%   genSDD(modelName, [], 'CI')
%   result = genSDD(modelName, ...)
%
%输入参数:
%   modelName - Simulink模型名称（字符串）
%
%可选参数:
%   authorNames - 作者姓名列表（字符串或字符串元胞数组）
%   'CI' - 持续集成环境模式
%   'DEV' - 开发环境模式（默认）
%
%输出参数:
%   result - 结构体（可选），包含报告生成结果信息
%            .Message - 报告生成结果消息
%            .ReportPath - 生成的报告文件路径
%
%说明:
%   - 检查Simulink Report Generator许可证是否可用
%   - 关闭所有当前打开的模型以避免冲突
%   - 验证模型启动脚本是否存在
%   - 加载并打开指定的模型
%   - 根据环境配置确定报告格式
%   - 配置SDD报告生成参数
%   - 生成并保存SDD报告
%
%报告内容:
%   SDD报告通常包含以下内容：
%   - 系统概述和架构
%   - 模型结构和层次
%   - 子系统详细设计
%   - 接口定义和数据流
%   - 算法实现描述
%   - 设计约束和假设
%
%环境模式:
%   DEV模式：开发环境，生成详细格式的报告
%   CI模式：持续集成环境，生成简化格式的报告
%
%报告格式:
%   报告格式由getReportFormatConfig函数根据环境确定：
%   - 支持PDF、HTML、Word等多种格式
%   - 格式选择基于项目配置和环境设置
%
%先决条件:
%   - 需要Simulink Report Generator许可证
%   - 模型启动脚本 'open_[ModelName].m' 必须存在
%   - 模型必须包含适当的文档和注释
%   - 项目结构必须正确配置
%
%示例:
%   % 生成基本SDD报告
%   genSDD('MyModel');
%
%   % 指定作者的SDD报告
%   result = genSDD('MyModel', 'John Doe');
%   fprintf('SDD报告已生成: %s\n', result.ReportPath);
%
%   % 多作者SDD报告
%   authors = {'John Doe', 'Jane Smith', 'Bob Wilson'};
%   genSDD('MyModel', authors);
%
%   % CI环境中的批量SDD生成
%   models = getModelList();
%   for i = 1:length(models)
%       try
%           genSDD(models{i}, [], 'CI');
%           fprintf('✓ %s SDD报告生成完成\n', models{i});
%       catch ME
%           fprintf('✗ %s SDD报告生成失败: %s\n', models{i}, ME.message);
%       end
%   end
%
%报告配置:
%   - 报告标题：模型名称
%   - 报告副标题：'Design Description'
%   - 作者信息：可通过参数指定
%   - 模板：使用StdRpt.SDD标准模板
%
%输出文件:
%   报告文件存储在项目标准目录结构中，文件名格式为：
%   [ModelName]_SDD.[format]
%
%依赖项:
%   dig.isProductInstalled - 检查产品安装状态
%   bdclose - 关闭Simulink模型
%   evalin - 在工作空间执行代码
%   StdRpt.SDD - 标准SDD报告配置类
%   getReportFormatConfig - 获取报告格式配置
%
%参见:
%   StdRpt, Simulink.Report, rptgen, getReportFormatConfig
%

%版本: 1.0
%日期: 2021-2024
%


if ~dig.isProductInstalled('Simulink Report Generator')
    error('A Simulink Report Generator license is not available.');
end

% Close all models.
bdclose('all');

% Check for prerequisites.
if ~exist(['open_', modelName], 'file')
    error(['Model startup script ''open_', modelName, ''' not found.']);
end

% Open the model.
disp(['Opening Simulink model ', modelName, '.']);
evalin('base', ['open_', modelName]);

% Determine environment and get report format from project configuration
if nargin > 2 && ~isempty(varargin{2})
    % CI environment
    environment = 'CI';
else
    % DEV environment  
    environment = 'DEV';
end

% Get report format using the centralized configuration function
reportFormat = getReportFormatConfig('SDD report', environment);

% % Load libraries in the dependency to avoid warnings in the requirement
% % section.
% libs = getLibDependency(modelName);
% load_system(libs);

% Create a configuration for SDD report generation.
sddCfg = StdRpt.SDD(modelName);
% sddCfg.rootSystem = modelName;
sddCfg.title = modelName;
sddCfg.subtitle = 'Design Description';
if nargin > 1 && ~isempty(varargin{1})
    sddCfg.authorNames = varargin{1};
else
    % Leave it at default.
end
sddCfg.titleImgPath = ''; % To be customized.
sddCfg.legalNotice = ''; % To be customized.
sddCfg.timeFormat = ''; % To be customized.
sddCfg.includeDetails = true;
sddCfg.includeModelRefs = false;
sddCfg.includeCustomLibraries = false; % To be customized.
sddCfg.includeLookupTables = true;
sddCfg.includeRequirementsLinks = true;
sddCfg.includeGlossary = true;
% Set output format based on project configuration
if strcmpi(reportFormat, 'pdf')
    sddCfg.outputFormat = 1; % pdf file
elseif strcmpi(reportFormat, 'html')
    sddCfg.outputFormat = 6; % a single html file
elseif strcmpi(reportFormat, 'docx')
    sddCfg.outputFormat = 5; % docx
elseif strcmpi(reportFormat, 'doc')
    sddCfg.outputFormat = 3; % docx
else
    sddCfg.outputFormat = 10;
end

sddCfg.stylesheetIndex = 1;
sddCfg.outputName = [modelName, '_SDD']; % Base name without extension

sddCfg.outputDir = ProjectPathManager.getDirPath('SDD report', modelName);
% 确保输出目录存在
if ~exist(sddCfg.outputDir, 'dir')
    mkdir(sddCfg.outputDir);
    fprintf('✅ 创建SDD报告目录: %s\n', sddCfg.outputDir);
end


sddCfg.incrOutputName = 0;
sddCfg.packageType = 1;
sddCfg.UseStatusWindow = false;
if nargin > 2 && ~isempty(varargin{2})
    sddCfg.displayReport = false;
else
    sddCfg.displayReport = true;
end

% Generate the report.
sddCfg.run();

% Close the model.
disp(['Closing Simulink model ', modelName, '.']);
close_system(modelName, 0);

result.Message = ['SDD report (', upper(reportFormat), ') for ', modelName, ' is successfully generated.'];
if nargout > 0
    varargout{1} = result;
end
disp(result.Message);

end
